package org.paboo.chart.datamatrix;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

import javax.imageio.ImageIO;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.paboo.Util.ParameterObject;
import org.paboo.codec.Base64;
import org.paboo.http.BaseServlet;
import org.paboo.http.HttpMethod;

import com.google.gson.Gson;

public class DmServlet extends BaseServlet {

	private static final long serialVersionUID = 3525032759250925015L;
	private Logger log = LogManager.getLogger(getClass());

	public void init(ServletConfig config) throws ServletException {
		super.init(config);
	}

	protected void processRequest(HttpServletRequest request, HttpServletResponse response, HttpMethod method)
			throws IOException {
		DmEntity e = new DmEntity();
		if (method == HttpMethod.GET) {
			String ctx = getParameterWithDefault(request, "data", ParameterObject.DEFAULT_CONTECT);
			String encoding = ParameterObject.hasText(request.getCharacterEncoding()) ? request.getCharacterEncoding() : "UTF-8";
			ctx = URLDecoder.decode(ctx, encoding);
			ctx = new String(ctx.getBytes(encoding), StandardCharsets.ISO_8859_1);
			e.setData(ctx);

			String format = getParameterWithDefault(request, "format", "png");
			if (format.contains("|")) {
				String[] f = format.split("\\|");
				format = f[0];
				e.setNeedBase64(f[1].toLowerCase().equalsIgnoreCase("base64"));
			} else {
				e.setNeedBase64(false);
			}
			e.setFormat(format);
			String[] size = getParameterWithDefault(request, "size", "128x128").split("x");
			e.setWidth(Integer.valueOf(size[0]));
			e.setHeight(Integer.valueOf(size[1]));
		} else if (method == HttpMethod.POST) {
			BufferedReader br = new BufferedReader(
					new InputStreamReader(request.getInputStream(), request.getCharacterEncoding()));
			Gson gson = new Gson();
			e = gson.fromJson(br, DmEntity.class);
			if(!ParameterObject.hasText(e.getData())){
				e.setData(ParameterObject.DEFAULT_CONTECT);
			}
			if(!ParameterObject.hasText(e.getFormat())){
				e.setFormat("png");
			}
			if(!ParameterObject.hasInteger(e.getWidth()) || !ParameterObject.hasInteger(e.getWidth())) {
				e.setHeight(128);
				e.setWidth(128);
			}
			if(!ParameterObject.hasBoolean(e.isNeedBase64())){
				e.setNeedBase64(false);
			}
			log.info(gson.toJson(e));
		} else {
			response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "Request error!!!");
			return;
		}
		
		BufferedImage data = null;
		try {
			data = ZxingUtil.encode(e.getData(), e.getWidth(), e.getHeight());
		} catch (IllegalArgumentException ex) {
			String errorMsg = "Create Fail!!!";
			if (log.isDebugEnabled()) {
				log.error(errorMsg, ex);
			} else {
				log.error(errorMsg);
			}
			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, errorMsg);
			return;
		}

		ByteArrayOutputStream out = new ByteArrayOutputStream();
		if (!ImageIO.write(data, e.getFormat(), out)) {
			log.error("Could not write an image of format " + e.getFormat());
			throw new IOException("Could not write an image of format " + e.getFormat());
		}
		if (e.isNeedBase64()) {
			String base64 = Base64.encodeToString(out.toByteArray());
			response.setContentType("text/plain");
			response.getOutputStream().print(base64);
		} else {
			response.setContentType("image/" + e.getFormat());
			response.setContentLength(out.size());
			response.getOutputStream().write(out.toByteArray());
		}
	}
}
